﻿using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Client.Options;
using MQTTnet.Client.Publishing;
using MQTTnet.Protocol;
using MySqlX.XDevAPI;
using PmSoft;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Modules.MQTT
{
    /// <summary>
    /// Mqtt工厂
    /// </summary>
    [UseDI(ServiceLifetime.Singleton)]
    public class MqttRepository
    {
        private readonly IConfiguration configuration;
        private readonly MqttFactory factory;
        private readonly IMqttClient mqttClient;
        private readonly IMqttClientOptions clientOptions;

        public MqttRepository(IConfiguration configuration, MqttFactory mqttFactory)
        {
            this.configuration = configuration;
            string? brokerAddress = configuration.GetValue<string>("MQTTOptions:BrokerAddress");
            int? port = configuration.GetValue<int>("MQTTOptions:Port");
            string? clientId = configuration.GetValue<string>("MQTTOptions:ClientId");
            string? username = configuration.GetValue<string>("MQTTOptions:UserName");
            string? password = configuration.GetValue<string>("MQTTOptions:PassWord");
            factory = new MqttFactory(); // 创建MQTT工厂
            clientOptions = new MqttClientOptionsBuilder() // 创建MQTT客户端选项
           .WithTcpServer(brokerAddress, port) // 设置服务器地址
               .WithClientId(clientId) // 设置客户端ID
               .WithCredentials(username, password) // 设置用户名和密码
               .Build();
            mqttClient = factory.CreateMqttClient();
            mqttClient.ConnectAsync(clientOptions, CancellationToken.None); // 连接到MQTT服务器
        }

        /// <summary>
        /// 发布消息
        /// </summary>
        /// <param name="topic">发布消息的主题</param>
        /// <param name="message">要发布的消息内容</param>
        /// <returns></returns>
        public async Task<MqttClientPublishResult> PublishAsync(string topic, string message)
        {
            if (!mqttClient.IsConnected)
            {
                await mqttClient.ConnectAsync(clientOptions, CancellationToken.None); // 连接到MQTT服务器
            }
            topic = Uri.UnescapeDataString(topic);
            //// 订阅主题
            //var subscription = await mqttClient.SubscribeAsync(topic, MqttQualityOfServiceLevel.ExactlyOnce);
            var mqttMessage = new MqttApplicationMessageBuilder()
                .WithTopic(topic) // 设置主题
                .WithPayload(message) // 设置消息内容
                .WithAtMostOnceQoS()
                .WithRetainFlag() // 设置是否进行消息保留
                .Build();
            var result = await mqttClient.PublishAsync(mqttMessage, CancellationToken.None); // 发布消息
            return result;
        }
    }
}
